/**************************************************************
 * @file     bsp_uart_driver.c
 * @brief    串口驱动BSP层，接收串口中断的通知，发出数据就绪的通知
 * @author   Ruilist
 * @date     2025-08-10
 * @version  V1.0.0
 * @copyright Copyright (c) 2025
 *
 * @note     1 tab = 4 space
 *           依赖 Circular_buffer.h 中间件获得环形缓冲区
 *
 * @par 日志:
 * - V1.0.0 2025-08-10 Ruilist
 *   接收串口中断的通知，发出数据就绪的通知
 **************************************************************/

//******************************** Includes *********************************//

#include "bsp_uart_driver.h"

//******************************** Includes *********************************//

//******************************** Defines **********************************//

osThreadId_t bsp_uart_driver_TaskHandle = NULL;

const osThreadAttr_t bsp_uart_driver_attributes = {
    .name       = "bsp_uart_driver_Task",
    .stack_size = 128 * 5,
    .priority   = (osPriority_t)osPriorityNormal,
};

circular_buffer_t *p_uart_buffer = NULL;  // 环形缓冲区指针

//******************************** Defines **********************************//

//*********************Thread_Func **********************//

//*********************Thread_Func **********************//

//*********************Queue_Handler ********************//

SemaphoreHandle_t bsp_uart_irq_count = NULL;

//*********************Queue_Handler ********************//

//******************************** Declaring ********************************//

void bsp_uart_driver_Task_func( void *argument )
{
    log_i( "bsp uart driver Task start \r\n" );

    if ( CIRCULAR_BUFFER_OK != create_circular_buffer( &p_uart_buffer ) )
    {
        log_e( "bsp uart driver Task create circular buffer error \r\n" );
        return;
    }
    log_i( "p_uart_buffer is[%p] \r\n", p_uart_buffer );

    bsp_uart_irq_count = xSemaphoreCreateCounting( 4, 0 );
    if ( NULL == bsp_uart_irq_count )
    {
        log_e( "bsp_uart_irq_count created failed\r\n" );
        return;
    }

    log_i( "bsp uart driver Task init successfully \r\n" );

    if ( HAL_OK != HAL_UARTEx_ReceiveToIdle_DMA( &huart1, p_uart_buffer->data, CIRCULAR_BUFFER_SIZE ) )
    {
        log_e( "HAL_UARTEx_ReceiveToIdle_DMA  failed\r\n" );
    }

#if 0  // 环形缓冲区测试
    uint8_t data = 0;
    if ( BUFFER_IS_EMPTY == circular_buffer_status( p_uart_buffer ) )
    {
        log_i( "p_uart_buffer is empty \r\n" );
    }

    for ( uint8_t i = 0; i < 11; i++ )
    {
        if ( CIRCULAR_BUFFER_OK == insert_circular_buffer( p_uart_buffer, i ) )
        {
            log_i( " p_uart_buffer->data[%d] is [%x]\r\n", i, p_uart_buffer->data[i] );
        }
        if ( BUFFER_IS_FULL == circular_buffer_status( p_uart_buffer ) )
        {
            log_i( "p_uart_buffer is FULL \r\n" );
            break;
        }
    }

    for ( uint8_t i = 0; i < 11; i++ )
    {
        if ( CIRCULAR_BUFFER_OK == read_circular_buffer( p_uart_buffer, &data ) )
        {
            log_i( " read circular buffer is [%x]\r\n", data );
        }
        if ( BUFFER_IS_EMPTY == circular_buffer_status( p_uart_buffer ) )
        {
            log_i( "p_uart_buffer is empty \r\n" );
            break;
        }
    }
#endif

    for ( ;; )
    {
        if ( pdTRUE == xSemaphoreTake( bsp_uart_irq_count, portMAX_DELAY ) )
        {
            log_i( "bsp uart driver Task xSemaphoreTake successfully \r\n" );
            if ( pdTRUE == xSemaphoreGive( bsp_to_parse_count ) )
            {
                log_i( "bsp uart driver Give xSemaphoreTake successfully \r\n" );
            }
        }
        osDelay( 1 );
    }
}

#ifdef __CIRCULAR_BUFFER_H__
Circular_buffer_status_t bsp_get_buffer_address( circular_buffer_t **p_buffer )
{
    if ( NULL == p_buffer )
    {
        log_e( "incoming parameter error-[%d]\r\n", INCOME_PARAM_ERROR );
        return INCOME_PARAM_ERROR;
    }
    *p_buffer = p_uart_buffer;
    if ( NULL == ( *p_buffer ) )
    {
        log_e( "get buffer address faild-[%d]\r\n", CIRCULAR_BUFFER_ERROR );
        return CIRCULAR_BUFFER_ERROR;
    }
    return CIRCULAR_BUFFER_OK;
}
#endif

void dma_half_irq_callback( uint32_t data_number )
{
    uint32_t circular_buffer_head = 0;
    uint32_t offset               = 0;
    log_i( "dma_half_irq_callback data number is[%d]\r\n", data_number );
    if ( CIRCULAR_BUFFER_OK != get_head_circular_buffer( p_uart_buffer, &circular_buffer_head ) )
    {
        log_w( "dma_half_irq_callback get_head_circular_buffer error\r\n" );
    }
    // 计算指针偏移量
    offset = CIRCULAR_BUFFER_SIZE / 2 - circular_buffer_head % ( CIRCULAR_BUFFER_SIZE / 2 );

    if ( CIRCULAR_BUFFER_OK != head_offset_circular_buffer( p_uart_buffer, offset ) )
    {
        log_w( "dma_half_irq_callback head_offset_circular_buffer error\r\n" );
    }
    log_i( "p_uart_buffer head is[%d]\r\n", p_uart_buffer->head );

    BaseType_t xHigherPrioritTaskWoken = pdTRUE;
    if ( pdTRUE != xSemaphoreGiveFromISR( bsp_uart_irq_count, &xHigherPrioritTaskWoken ) )
    {
        log_w( "uart_idle_irq_callback xSemaphoreGiveFromISR error\r\n" );
    }
}

void dma_comp_irq_callback( uint32_t data_number )
{
    uint32_t circular_buffer_head = 0;
    uint32_t offset               = 0;
    log_i( "dma_comp_irq_callback data number is[%d]\r\n", data_number );
    if ( CIRCULAR_BUFFER_OK != get_head_circular_buffer( p_uart_buffer, &circular_buffer_head ) )
    {
        log_w( "dma_comp_irq_callback get_head_circular_buffer error\r\n" );
    }
    // 计算指针偏移量
    if ( 0 != circular_buffer_head % CIRCULAR_BUFFER_SIZE )
    {
        offset = CIRCULAR_BUFFER_SIZE - circular_buffer_head % CIRCULAR_BUFFER_SIZE;

        if ( CIRCULAR_BUFFER_OK != head_offset_circular_buffer( p_uart_buffer, offset ) )
        {
            log_w( "dma_comp_irq_callback head_offset_circular_buffer error\r\n" );
        }
    }
    else
    {
        if ( CIRCULAR_BUFFER_OK != head_offset_circular_buffer( p_uart_buffer, 10 ) )
        {
            log_w( "dma_comp_irq_callback head_offset_circular_buffer error\r\n" );
        }
    }
    log_i( "p_uart_buffer head is[%d]\r\n", p_uart_buffer->head );

    BaseType_t xHigherPrioritTaskWoken = pdTRUE;
    if ( pdTRUE != xSemaphoreGiveFromISR( bsp_uart_irq_count, &xHigherPrioritTaskWoken ) )
    {
        log_w( "uart_idle_irq_callback xSemaphoreGiveFromISR error\r\n" );
    }
}

void uart_idle_irq_callback( uint32_t data_number )
{
    uint32_t circular_buffer_head = 0;
    uint32_t offset               = 0;
    log_i( "uart_idle_irq_callback data number is[%d]\r\n", data_number );
    if ( CIRCULAR_BUFFER_OK != get_head_circular_buffer( p_uart_buffer, &circular_buffer_head ) )
    {
        log_w( "uart_idle_irq_callback get_head_circular_buffer error\r\n" );
    }
    // 计算指针偏移量
    offset = data_number - circular_buffer_head % CIRCULAR_BUFFER_SIZE;

    if ( CIRCULAR_BUFFER_OK != head_offset_circular_buffer( p_uart_buffer, offset ) )
    {
        log_w( "uart_idle_irq_callback head_offset_circular_buffer error\r\n" );
    }
    log_i( "p_uart_buffer head is[%d]\r\n", p_uart_buffer->head );

    BaseType_t xHigherPrioritTaskWoken = pdTRUE;
    if ( pdTRUE != xSemaphoreGiveFromISR( bsp_uart_irq_count, &xHigherPrioritTaskWoken ) )
    {
        log_w( "uart_idle_irq_callback xSemaphoreGiveFromISR error\r\n" );
    }
}
//******************************** Declaring ********************************//